<template>
  <div class="schedule_view">
    <div class="w-full">
      <Spin :spinning="loading">
        <div class="flex justify-between">
          <div class="flex items-center">
            <Space>
              <a-button @click="toggleCollapsed">
                <MenuUnfoldOutlined v-if="collapsed" />
                <MenuFoldOutlined v-else />
              </a-button>
              <template v-if="isDay">
                <RadioGroup v-model:value="initialView" button-style="solid" @change="handleView">
                  <RadioButton value="timeGridDay">日</RadioButton>
                  <RadioButton value="timeGridWeek">周</RadioButton>
                  <RadioButton value="dayGridMonth">月</RadioButton>
                </RadioGroup>
                <a-button @click="handleToday">{{
                  initialView == 'timeGridDay'
                    ? '今天'
                    : initialView == 'timeGridWeek'
                    ? '本周'
                    : initialView == 'dayGridMonth'
                    ? '本月'
                    : ''
                }}</a-button>
                <a-button @click="handleGoAllSchedule">全部日程</a-button>
              </template>
              <template v-else>
                <RadioGroup v-model:value="initialView" button-style="solid" @change="handleView">
                  <RadioButton value="resourceTimelineDay">日</RadioButton>
                  <RadioButton value="resourceTimelineWeek">周</RadioButton>
                  <RadioButton value="resourceTimelineMonth">月</RadioButton>
                </RadioGroup>
                <a-button @click="handleWeek">{{
                  initialView == 'resourceTimelineDay'
                    ? '今天'
                    : initialView == 'resourceTimelineWeek'
                    ? '本周'
                    : initialView == 'resourceTimelineMonth'
                    ? '本月'
                    : ''
                }}</a-button>
              </template>
            </Space>
          </div>
          <div>
            <a-button size="small" type="primary" @click="handlePreOrNext('prev')"
              ><left-outlined
            /></a-button>
            <span class="ml-2 mr-2">{{ title }}</span>
            <a-button size="small" type="primary" @click="handlePreOrNext('next')"
              ><right-outlined
            /></a-button>
          </div>
          <div>
            <Space>
              <Select
                :options="options"
                v-model:value="c_type"
                style="width: 150px"
                placeholder="请选择"
                mode="multiple"
                @change="handleCType"
              />
              <a-button type="primary" @click="handleCreate()" v-if="isDay">新增</a-button>
            </Space>
          </div>
        </div>
        <FullCalendar
          class="schedule_view_calendar"
          :options="calendarOptions"
          ref="fullCalendarRef"
        >
          <template #eventContent="arg">
            <span class="text-left hover:text-red-400 hover:underline cursor-pointer">
              <Tooltip>
                <template #title>
                  <div>
                    <div> {{ arg.timeText }}</div>
                    <div class="text_overflow">{{ arg.event.title }}</div>
                  </div>
                </template>
                <div
                  class="arg_content"
                  :class="{
                    arg_content_closed: arg?.event?.extendedProps?.closed,
                    arg_content_closed_un: !arg?.event?.extendedProps?.closed,
                  }"
                >
                  <Dropdown
                    :trigger="['hover']"
                    :overlayStyle="{ width: '100px', minWidth: '100px', zIndex: 10000000000000000 }"
                  >
                    <span>
                      <div> {{ arg.timeText }} </div>
                      <div class="text_overflow">{{ arg.event.title }}</div>
                    </span>
                    <template #overlay>
                      <Menu>
                        <MenuItem
                          key="1"
                          @click.stop="handleEdit(arg)"
                          v-if="isDay && !arg?.event?.extendedProps?.closed"
                          >编辑</MenuItem
                        >
                        <MenuItem
                          key="2"
                          @click.stop="handleDelete(arg)"
                          v-if="isDay && !arg?.event?.extendedProps?.closed"
                          >删除</MenuItem
                        >
                        <MenuItem key="2" @click.stop="handleEdit(arg, 'info')">详情</MenuItem>
                      </Menu>
                    </template>
                  </Dropdown>
                </div>
              </Tooltip>
            </span>
          </template>
        </FullCalendar>
      </Spin>
    </div>

    <AllScheduleDrawer @register="registerDrawer" @success="handleSuccess" />
  </div>
</template>
<script lang="ts" setup>
  import { ref, inject, onMounted, h } from 'vue';
  import FullCalendar from '@fullcalendar/vue3';
  import dayGridPlugin from '@fullcalendar/daygrid';
  import timeGridPlugin from '@fullcalendar/timegrid';
  import interactionPlugin from '@fullcalendar/interaction';
  import resourceTimelinePlugin from '@fullcalendar/resource-timeline'; // 引入需要的视图
  import { Space, Radio, Select, Dropdown, Menu, Spin, Tooltip } from 'ant-design-vue';
  import {
    MenuUnfoldOutlined,
    MenuFoldOutlined,
    RightOutlined,
    LeftOutlined,
  } from '@ant-design/icons-vue';
  import { useDrawer } from '/@/components/Drawer';
  import AllScheduleDrawer from '../allSchedule/AllScheduleDrawer.vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import {
    getPlanDel,
    getListPhase,
    getPlanListPhaseByUsers,
    getPlanListPhaseByDepts,
  } from '/@/api/workOffice/workOffice';
  import { options } from './scheduleView.data';
  import { isArray } from '/@/utils/is';
  import { dateUtil as dayjs } from '/@/utils/dateUtil';
  import { useDebounceFn } from '@vueuse/core';
  import { useGo } from '/@/hooks/web/usePage';
  const RadioGroup = Radio.Group;
  const RadioButton = Radio.Button;
  const MenuItem = Menu.Item;
  const { t } = useI18n();
  const { createMessage, createConfirm } = useMessage();
  const state = ref({
    beginDate: '',
    endDate: '',
  });
  const scrollTime = '07:00:00';
  // const c_type = ref(undefined);
  const c_type = ref(['0']);
  const fullCalendarRef = ref(null) as any;
  const title = ref('');
  const resourceEvent = ref<Recordable[]>([]);
  const resource = ref<Recordable[]>([]);
  const initialView = ref('timeGridWeek');
  const calendarOptions = ref({
    plugins: [
      dayGridPlugin,
      timeGridPlugin,
      interactionPlugin, // needed for dateClick
      resourceTimelinePlugin,
    ],
    // timeZone: 'UTC',
    scrollTime, //当切换到agenda时，初始滚动条滚动到的时间位置，默认在6点钟的位置
    headerToolbar: false,
    // headerToolbar: {
    //   left: 'prev,next today',
    //   center: 'title',
    //   right: 'dayGridMonth,timeGridWeek,timeGridDay',
    // },
    initialView: 'timeGridWeek', //resourceTimelineWeek resourceTimelineDay
    initialEvents: [], // alternatively, use the `events` setting to fetch from a feed
    editable: false, // 是否可以进行（拖动、缩放）修改
    selectable: true,
    selectMirror: true,
    dayMaxEvents: 50,
    contentHeight: 710,
    weekends: true,
    select: handleDateSelect,
    eventClick: handleEventClick,
    eventsSet: handleEvents,
    locale: 'zh-cn',
    firstDay: 1, //0是周日 1是周一 类推
    nowIndicator: true, // 现在的时间线显示
    resourceAreaHeaderContent: '',
    resourceAreaWidth: '150px',
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
    eventTimeFormat: {
      hour: 'numeric',
      minute: '2-digit',
      meridiem: false,
    },
    weekMode: 'variable',
    columnFormat: {
      month: 'dddd',
      week: 'dddd M-d',
      day: 'dddd M-d',
    },
    titleFormat: {
      // month: 'yyyy年 MMMM月',
      // week: "[yyyy年] MMMM月d日 { '—' [yyyy年] MMMM月d日}",
      // day: 'yyyy年 MMMM月d日 dddd',
    },
    buttonText: {
      today: '今天',
      month: '月视图',
      week: '周视图',
      day: '日视图',
    },
    allDayText: '全天',
    allDaySlot: false, //是否显示全天
    monthNames: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
    dayNames: ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
    // navLinks: false, //time不能跳转
    // navLinkDayClick: function (date, jsEvent) {
    //   console.log('navLinkDayClick', { date, jsEvent });
    //   const calendarApi = fullCalendarRef.value.getApi();
    //   calendarApi.gotoDate(date);
    //   day('timeGridDay');
    // },
    // events: [{ id: '1', resourceId: 'a', title: 'Meeting', start: new Date() }],
    // resources: [
    //   { id: 'a', title: 'Resource A' },
    //   { id: 'b', title: 'Resource B' },
    // ],
    resourceAreaColumns: [
      {
        field: 'title',
        headerContent: '',
      },
    ],
    resourceOrder: 'indexId', //索引 排序
    resources: function (fetchInfo, successCallback, failureCallback) {
      // console.log('开始时间' + fetchInfo.start.valueOf());
      successCallback(resource.value);
    },
    events: async function (info, successCallback, failureCallback) {
      const calendarApi = fullCalendarRef.value.getApi();
      // state.value.beginDate = dayjs(info.start).format('YYYY-MM-DD');
      // state.value.endDate = dayjs(info.end).format('YYYY-MM-DD');
      // const data = await fetch();
      // resourceEvent.value
      successCallback(resourceEvent.value);
    },
    // refetchResourcesOnNavigate: true,
    // resourceOrder: 'dispalyorder',
    // dayMaxEventRows: false,
    views: {
      resourceTimelineWeek: {
        slotDuration: { days: 1 },
        slotLabelFormat: [
          {
            month: 'numeric',
            day: 'numeric',
            weekday: 'long',
            hour12: false, // false设置时间为24小时
          },
        ],
      },
      resourceTimelineDay: {
        slotLabelFormat: {
          // 左侧时间格式
          hour: 'numeric',
          minute: 'numeric', //2-digit
          meridiem: 'lowercase',
          hour12: false, // false设置时间为24小时
        },
      },
      dayGridMonth: {
        dayHeaderFormat: {
          weekday: 'long',
        },
      },
      timeGridWeek: {
        slotLabelFormat: {
          // 左侧时间格式
          hour: 'numeric',
          minute: 'numeric', //2-digit
          meridiem: 'lowercase',
          hour12: false, // false设置时间为24小时
        },
        dayHeaderFormat: {
          weekday: 'long',
          month: 'numeric',
          day: 'numeric',
          omitCommas: true,
        },
      },
      timeGridDay: {
        slotLabelFormat: {
          // 左侧时间格式
          hour: 'numeric',
          minute: 'numeric', //2-digit
          meridiem: 'lowercase',
          hour12: false, // false设置时间为24小时
        },
      },
    },
    // resourceLabelContent(arg) {
    //   return {
    //     html: `<div>id: ${arg.resource.id}</div><div>title: ${arg.resource.title}</div>`,
    //   };
    // },
    /* you can update a remote database when these fire:
                      eventAdd:
                      eventChange:
                      eventRemove:
                      */
  });
  const currentEvents = ref([]);
  const isDay = ref(true);
  const setIsDay = () => {
    const { type } = fullCalendarRef.value?.getApi().view;
    isDay.value = type == 'dayGridMonth' || type == 'timeGridWeek' || type == 'timeGridDay';
  };
  const setTitle = () => {
    title.value = fullCalendarRef.value?.getApi().view.title;
  };
  function handleDateSelect(selectInfo) {
    if (type.value != '1') return;
    const record = {
      myDate: dayjs(selectInfo.start).format('YYYY-MM-DD HH:mm:ss'),
      endDate: dayjs(selectInfo.end).format('YYYY-MM-DD HH:mm:ss'),
    };
    handleCreate(record);
    let calendarApi = selectInfo.view.calendar;
    calendarApi.unselect(); // clear date selection
  }
  function handleEventClick(clickInfo) {}
  function handleEvents(events) {
    currentEvents.value = events;
  }
  const toggleCollapsed = inject('toggleCollapsed');
  const collapsed = inject('collapsed');

  async function day(val = 'timeGridWeek') {
    initialView.value = val;
    const calendarApi = fullCalendarRef.value.getApi();
    await calendarApi.changeView(val);
    setTitle();
    setIsDay();
    handleSuccess();
    // handleClear();
  }
  function colDay(val = 'resourceTimelineWeek') {
    initialView.value = val;
    const calendarApi = fullCalendarRef.value.getApi();
    calendarApi.changeView(val);
    setTitle();
    setIsDay();
    // handleClear();
    handleSuccess();
  }
  function handleToday() {
    const calendarApi = fullCalendarRef.value.getApi();
    calendarApi.today();
    setTitle();
    setIsDay();
    handleSuccess();
  }
  const handleWeek = () => {
    const calendarApi = fullCalendarRef.value.getApi();
    calendarApi.today();
    setTitle();
    handleSuccess();
    // calendarApi.addResource = [];
    // calendarApi.addEventSource([
    //   {
    //     id: '1',
    //     resourceId: 'a',
    //     title: '121233',
    //     start: new Date(),
    //   },
    // ]);
  };
  const handlePreOrNext = (val) => {
    const calendarApi = fullCalendarRef.value.getApi();
    switch (val) {
      case 'prev':
        calendarApi.prev();
        setTitle();
        break;
      case 'next':
        calendarApi.next();
        setTitle();
        break;
      default:
        break;
    }

    handleSuccess();
  };
  const handleView = async (e) => {
    const { value } = e.target;
    await day(value);
  };

  const handleCType = (val) => {
    handleSuccess();
  };

  const handleClear = () => {
    var otherComment = document.getElementsByClassName('fc-license-message'); //获取到的是一个类数组
    for (var i = 0; i < otherComment.length; i++) {
      otherComment[i].style.display = 'none';
    }
  };

  const type = ref('1');
  const users = ref('');
  const setUsersData = async (_type, _users) => {
    console.log('setUsersData', { _type, _users });
    try {
      users.value = _users;
      type.value = _type;
      switch (type.value) {
        case '1':
          day();
          break;
        case '2':
          colDay();
          break;
        case '3':
          colDay();
          break;
        case '4':
          colDay();
          break;
        case '5':
          colDay();
          break;
      }
    } catch (error) {
      console.error('setUsersData', error);
    }
  };
  const updateSize = () => {
    handleSuccess();
  };
  defineExpose({
    setUsersData,
    updateSize,
  });

  const [registerDrawer, { openDrawer }] = useDrawer();

  function handleCreate(record = {}) {
    openDrawer(true, {
      isUpdate: false,
      record,
    });
  }

  function handleEdit(arg, type = '') {
    const record = resourceEvent.value.find((item) => item.id == arg.event.id);
    openDrawer(true, {
      record,
      isUpdate: true,
      type,
    });
  }

  async function handleDelete(record: Recordable) {
    createConfirm({
      iconType: 'warning',
      title: () => h('span', t('common.prompt')),
      content: () => h('span', '您确定要删除么'),
      onOk: async () => {
        try {
          await getPlanDel({ id: record.event.id }).then(() => {
            handleSuccess();
            createMessage.success('删除成功');
          });
        } catch (err) {
          console.error(err);
        }
      },
    });
  }
  const fetch = async () => {
    const calendarApi = fullCalendarRef.value.getApi();
    setTitle();
    const viewType = calendarApi.view.type;
    if (viewType == 'timeGridDay' || viewType == 'resourceTimelineDay') {
      state.value.beginDate = dayjs(calendarApi.view.activeStart).format('YYYY-MM-DD');
      state.value.endDate = state.value.beginDate;
    } else {
      state.value.beginDate = dayjs(calendarApi.view.activeStart).format('YYYY-MM-DD');
      state.value.endDate = dayjs(calendarApi.view.activeEnd).format('YYYY-MM-DD');
    }
    resourceEvent.value = [];
    resource.value = [];
    if (type.value == '1') {
      const res = await getListPhase({
        beginDate: state.value.beginDate,
        endDate: state.value.endDate,
        actionType: isArray(c_type.value) && c_type.value.length ? c_type.value.join(',') : '',
      });
      if (res.list && res.list.length > 0) {
        const list = res.list;
        list.forEach((m) => {
          for (let v in m) {
            const temp = m[v];
            if (isArray(temp) && temp.length) {
              temp.forEach((item) => {
                if (viewType == 'dayGridMonth' || viewType == 'timeGridDay') {
                  resourceEvent.value.push({
                    ...item,
                    title: `${item.title}`,
                    start: `${item.myDate}`,
                    end: item.endDate,
                  });
                } else {
                  // timeGridWeek
                  for (let n in item) {
                    const td = item[n];
                    if (isArray(td) && td.length) {
                      td.forEach((t) => {
                        resourceEvent.value.push({
                          ...t,
                          title: `${t.title}`,
                          start: t.myDate,
                          end: t.endDate,
                        });
                      });
                    }
                  }
                }
              });
            }
          }
        });
      }
    } else {
      const params: Recordable = {
        beginDate: state.value.beginDate,
        endDate: state.value.endDate,
        actionType: isArray(c_type.value) && c_type.value.length ? c_type.value.join(',') : '',
      };
      let api: any = null;
      if (users.value) {
        if (type.value == '5') {
          params.deptCodes = users.value;
          api = getPlanListPhaseByDepts;
        } else {
          params.users = users.value;
          api = getPlanListPhaseByUsers;
        }
        const res = await api(params);
        if (res && res.length) {
          res.forEach((it, ind) => {
            resource.value.push({
              title: it.realName,
              id: it.userName,
              indexId: ind,
            });
            if (it.list && it.list.length) {
              it.list.forEach((m) => {
                for (let v in m) {
                  const temp = m[v];
                  if (isArray(temp) && temp.length) {
                    temp.forEach((item) => {
                      if (
                        viewType == 'resourceTimelineMonth' ||
                        viewType == 'resourceTimelineDay'
                      ) {
                        resourceEvent.value.push({
                          ...item,
                          title: `${item.title}`,
                          start: `${item.myDate}`,
                          end: item.endDate,
                          resourceId: item.userName,
                        });
                      } else {
                        for (let n in item) {
                          const td = item[n];
                          if (isArray(td) && td.length) {
                            td.forEach((t) => {
                              resourceEvent.value.push({
                                ...t,
                                title: `${t.title}`,
                                start: `${t.myDate}`,
                                end: t.endDate,
                                resourceId: t.userName,
                              });
                            });
                          }
                        }
                      }
                    });
                  }
                }
              });
            }
          });
        }
      } else {
        resourceEvent.value = [];
      }
    }

    return resourceEvent.value;
  };
  const loading = ref(false);
  async function reFresh() {
    try {
      const calendarApi = fullCalendarRef.value.getApi();
      loading.value = true;
      await fetch();
      await calendarApi.refetchEvents();
      await calendarApi.refetchResources();
    } catch (error) {
      console.error(error);
    } finally {
      loading.value = false;
    }
  }
  // 防抖，延迟500ms执行
  const handleSuccess = useDebounceFn(reFresh, 500);
  onMounted(day);
  const go = useGo();
  //go allSchedule
  const handleGoAllSchedule = () => {
    go('/allSchedule');
  };
</script>

<style lang="less" scoped>
  .schedule_view {
    display: flex;
    min-height: 100%;
    font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
    font-size: 14px;
    flex-grow: 1;
    padding: 0 5px;
  }
  .schedule_view_calendar {
    width: 100%;
  }
  :deep(.fc .fc-button-primary) {
    background-color: @button-primary-color;
    border-color: @button-primary-color;
    box-shadow: none;
  }
  :deep(.fc .fc-button-primary:not(:disabled).fc-button-active),
  :deep(.fc .fc-button-primary:not(:disabled):active) {
    background-color: @button-primary-hover-color;
    border-color: @button-primary-hover-color;
    box-shadow: none;
  }
  :deep(.fc-v-event) {
    border: none;
    // border-left: 2px solid #66c23c;
    // border-top: none;
    // border-right: none;
    // border-bottom: none;
  }
  :deep(.fc-event-main) {
    // background-color: #eef9eb;
    // color: @button-primary-hover-color;
    color: rgba(0, 0, 0, 0.85);
  }
  :deep(
      .fc-timegrid-event-harness-inset .fc-timegrid-event,
      .fc-timegrid-event.fc-event-mirror,
      .fc-timegrid-more-link
    ) {
    box-shadow: none;
  }
  .text_overflow {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  :deep(a) {
    color: rgba(0, 0, 0, 0.85);
    font-weight: 400;
  }

  .arg_content {
    height: 100%;
  }
  .arg_content_closed {
    background-color: #eef9eb;
    border-left: 2px solid #66c23c;
  }
  .arg_content_closed_un {
    background-color: #a5c3f0;
    border-left: 2px solid #87b1e9;
  }
</style>
